/**
 * 
 */
package com.zufangbao.earth.web.controller.particalsystem;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Page;
import com.demo2do.core.web.resolver.Secure;
import com.zufangbao.earth.PageView;
import com.zufangbao.earth.RoleSpec;
import com.zufangbao.earth.ViewEntry;
import com.zufangbao.earth.entity.contractpartical.ContractPartical;
import com.zufangbao.earth.entity.particalsystem.AppParticles;
import com.zufangbao.earth.entity.security.Principal;
import com.zufangbao.earth.handler.BillDepositeHandler;
import com.zufangbao.earth.handler.CookieHandler;
import com.zufangbao.earth.service.AppParticlesService;
import com.zufangbao.earth.service.AuthorisedBillSketchService;
import com.zufangbao.earth.service.ContractParticalService;
import com.zufangbao.earth.service.ParticalModelService;
import com.zufangbao.earth.service.ParticalService;
import com.zufangbao.earth.web.interceptor.ViewCategoryValidation;
import com.zufangbao.gluon.api.quark.AuthorisedBillSketch;
import com.zufangbao.gluon.exception.CommonException;
import com.zufangbao.gluon.handler.BaseViewSpecHandler;
import com.zufangbao.gluon.handler.ResultHandler;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth;
import com.zufangbao.gluon.spec.global.GlobalCodeSpec;
import com.zufangbao.gluon.spec.global.GlobalMsgSpec;
import com.zufangbao.gluon.spec.global.GlobalMsgSpec.GeneralErrorMsg;
import com.zufangbao.sun.entity.contract.Contract;
import com.zufangbao.sun.entity.order.Order;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.ContractService;
import com.zufangbao.sun.service.OrderService;


/**
 * @author wukai
 *
 */
@Controller("contractPaticalController")
@RequestMapping("/contract-partical")
@MenuSetting("menu-data")
public class ContractParticalController {
	
	@Qualifier("viewSpecHandler")
	@Autowired
	private BaseViewSpecHandler redirectSpecHandler;
	
	@Autowired
	private CookieHandler cookieHandler;
	
	@Autowired
	private ParticalService particalService;
	
	@Autowired
	private ParticalModelService particalModelService;
	
	@Autowired
	private ResultHandler resultHandler;
	
	@Autowired
	private ContractParticalService contractParticalService;
	
	@Autowired
	private AppService appService;
	
	@Autowired
	private AppParticlesService appParticleService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private ContractService contractService;
	
	@Autowired
	private AuthorisedBillSketchService authorisedBillSketchService;
	
	@Autowired
	private BillDepositeHandler billDepositeHandler;
	
	public static final Log logger = LogFactory.getLog(ContractParticalController.class);
	
	@RequestMapping("/partical-contracts-list")
	@MenuSetting("submenu-union-contracts")
	@ViewCategoryValidation
	public ModelAndView loadAssignParticalContracts(@Secure Principal principal, String particalUniqueId, Page page, HttpServletRequest request) {
		
		try {
			
			ViewEntry viewCategory = getViewCategoryFromCookie(request, principal);
			
			String appId = viewCategory.getAppId();
			
			List<AppParticles> quarkParticles = appParticleService.getQuarkPartical(viewCategory.getAppId());
			
			if(CollectionUtils.isEmpty(quarkParticles)){
				
				logger.error("the appId["+viewCategory.getAppId()+"] quark partical is empty");
				
				return redirectSpecHandler.errorSpec(GlobalMsgSpec.GeneralErrorMsg.MSG_NO_DATA);
			}
			
			particalUniqueId = quarkParticles.get(0).getUniqueParticalId();
			
			List<ContractPartical> contractParticals = contractParticalService.listAssignContracByUniqueIdAndAppId(particalUniqueId, appId, page);;
			
			ModelAndView modelAndView = new ModelAndView(PageView.PAGE_LOAD_ASSIGN_CONTRACTS);
			
			modelAndView.addObject("particalcontracts", contractParticals);
			
			modelAndView.addObject("particalUniqueId", particalUniqueId);
			
			modelAndView.addObject("particals", particalService.loadAllQuarksByAppId(appId));
			
			return modelAndView;
			
		} catch (Exception e) {
			
			logger.error("list partical contracts error: " + e.getMessage());
			
			return redirectSpecHandler.errorSpec();
		}
		
	}

	@RequestMapping("/{particalUniqueId}/assign-contracts")
	public ModelAndView loadNoAssignContracts(@Secure Principal principal,
			@PathVariable("particalUniqueId")String uniqueId, Page page, HttpServletRequest request) {
		
		try {
			
			ViewEntry viewCategory = getViewCategoryFromCookie(request, principal);
			
			String appId = viewCategory.getAppId();
			
			List<Contract> noAssignContracts = contractParticalService.listNoAssignContract(appId, page);
			
			ModelAndView modelAndView = new ModelAndView(PageView.PAGE_LOAD_ALL_NOASSIGN_CONTRACT);
			
			modelAndView.addObject("noAssignContracts", noAssignContracts);
			
			modelAndView.addObject("particalUniqueId", uniqueId);
			
			return modelAndView;
			
		} catch (Exception e) {
			
			logger.info("load no assign contracts occur error["+e.getMessage()+"]");
			
			return redirectSpecHandler.errorSpec();
		}
	}

	@RequestMapping(value = "/do-assign-contracts", method = RequestMethod.POST)
	public @ResponseBody String assignContract(@Secure Principal principal, @RequestParam("uniqueId")String uniqueId,
			String contractIds) {
		try {
		
			if(StringUtils.isEmpty(uniqueId) || StringUtils.isEmpty(contractIds)){
				
				return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_ILLEGAL_REQ);
			}
			@SuppressWarnings("unchecked")
			List<Integer> originalContractIdList = JsonUtils.parse(contractIds, List.class);
			
			if(CollectionUtils.isEmpty(originalContractIdList)){
				
				return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_ILLEGAL_REQ);
			}
			List<Long> contractIdList = new ArrayList<Long>();
			
			for(Integer item : originalContractIdList){
				
				contractIdList.add(Long.parseLong(String.valueOf(item)));
			}
			
			List<Order> orderList = new ArrayList<Order>();
			
			for(Long contractId : contractIdList){
				
				Contract contract = contractService.getContract(contractId);
				
				List<Order> tempOrderList = orderService.getOrderList(contract);
				
				if(CollectionUtils.isEmpty(tempOrderList)){
					
					return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_ILLEGAL_REQ);
				}
				orderList.addAll(tempOrderList);
				
			}
		
			List<AuthorisedBillSketch> authorisedBillSketchs = null;
			
			authorisedBillSketchs = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
			boolean isAssignBillSuc = billDepositeHandler.assignBills(uniqueId, authorisedBillSketchs);
			
			if( !isAssignBillSuc ){
				
				return resultHandler.errorJsonResult(GlobalCodeSpec.CODE_FAILURE,GeneralErrorMsg.MSG_SYSTEM_ERROR);
			}
			contractParticalService.assignContracts(uniqueId, contractIdList);
		
			return resultHandler.sucJsonResult();
			
		} catch (CommonException e) {
			
			return resultHandler.errorJsonResult(e.getErrorCode(),GeneralErrorMsg.MSG_SYSTEM_ERROR);
		}
		catch (Exception e) {
			
			return resultHandler.errorJsonResult(GeneralErrorMsg.MSG_SYSTEM_ERROR);
		}
	}
	@RequestMapping(value = "/do-revoke-contracts", method = RequestMethod.POST)
	public @ResponseBody String revokeContract(@Secure Principal principal, String uniqueId,
			String contractIds) {
		
		try {
		
			if(StringUtils.isEmpty(uniqueId) || StringUtils.isEmpty(contractIds)){
				
				return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_SYSTEM_ERROR);
			}
			@SuppressWarnings("unchecked")
			List<Integer> originalContractIdList = JsonUtils.parse(contractIds, List.class);
			
			if(CollectionUtils.isEmpty(originalContractIdList)){
				
				return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_SYSTEM_ERROR);
			}
			List<Long> contractIdList = new ArrayList<Long>();
			
			List<Order> orderList = new ArrayList<Order>();
			
			for(Integer item : originalContractIdList){
				
				contractIdList.add(Long.parseLong(String.valueOf(item)));
			}
			for(Long contractId : contractIdList){
				
				Contract contract = contractService.getContract(contractId);
				
				contractService.saveOrUpdate(contract);
				
				List<Order> tempOrderList = orderService.getOrderList(contract);
				
				if(CollectionUtils.isEmpty(tempOrderList)){
					
					return resultHandler.errorJsonResult(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS,GeneralErrorMsg.MSG_ILLEGAL_REQ);
				}
				orderList.addAll(tempOrderList);
			}
			
			List<String> authorisedBillSketchUniqueIds = null;
		
			authorisedBillSketchUniqueIds = authorisedBillSketchService.getUniuqueBillIds(orderList);
			
			boolean isRevokeBillSuc = billDepositeHandler.revokeBills(uniqueId, authorisedBillSketchUniqueIds);
			
			if( !isRevokeBillSuc ){
				
				return resultHandler.errorJsonResult(GlobalCodeSpec.CODE_FAILURE,GeneralErrorMsg.MSG_SYSTEM_ERROR);
			}
			
			contractParticalService.revokeContracts(uniqueId, contractIdList);
		
			return resultHandler.sucJsonResult();
			
		} catch (CommonException e) {
			
			return resultHandler.errorJsonResult(e.getErrorCode(),GeneralErrorMsg.MSG_SYSTEM_ERROR);
			
		}
		catch (Exception e) {
			
			return resultHandler.errorJsonResult(GeneralErrorMsg.MSG_SYSTEM_ERROR);
		}
		
	}
	private ViewEntry getViewCategoryFromCookie(HttpServletRequest request, Principal principal) throws CommonException{
		
		ViewEntry viewCategory = JsonUtils.parse(cookieHandler.getCookie(GlobalSpec4Earth.PARAM_VIEW_CATEGORY, request).toString(),ViewEntry.class);
		
		if(null == viewCategory){
			
			throw new CommonException(GlobalCodeSpec.GeneralErrorCode.ERROR_ILLEGAL_PARAM);
		}
		
		if(!RoleSpec.ROLE_SUPER_USER.equals(principal.getAuthority())){
			
			if(!viewCategory.getRole().equals(principal.getAuthority())){
				
				throw new CommonException(GlobalCodeSpec.GeneralErrorCode.ERROR_NO_AUTHORITY);
			}
			
		}
		return viewCategory;
	}

}
